#include<fstream>
#include<string>
#include<vector>
#include<map>
#include"find_editor_path.h"

std::vector<std::string> getTextFromInput(const char* path){
	std::ifstream input(path);
	std::vector<std::string> listOfStrings;
	std::string inputString;
	while (getline(input, inputString)){
		listOfStrings.push_back(inputString);
	}
	input.close();
	return listOfStrings;
}

void getHashesFromInput(const std::vector<std::string>& listFromFirstInput,
	const std::vector<std::string>& listFromSecondInput,
	std::map<std::string, long long>& keys,
	std::vector<std::string>& keysReverse,
	std::vector<long long>& hashes1,
	std::vector<long long>& hashes2
	){
	long long currentHash = 0;
	for (auto currentString: listFromFirstInput){
		if (keys.find(currentString) != keys.end())
			hashes1.push_back(keys[currentString]);
		else{
			keys[currentString] = currentHash;
			keysReverse.push_back(currentString);
			
			hashes1.push_back(currentHash);
			++currentHash;
		}
	}
	for (auto currentString : listFromSecondInput){
		if (keys.find(currentString) != keys.end())
			hashes2.push_back(keys[currentString]);
		else{
			keys[currentString] = currentHash;
			keysReverse.push_back(currentString);
			hashes2.push_back(currentHash);
			++currentHash;
		}
	}
}

void outputEditorChanges(const char* path,
	const std::map<std::string, long long>& keys,
	const std::vector<std::string>& keysReverse,
	const std::vector<long long>& hashes1,
	const std::vector<long long>& hashes2,
	const std::vector<std::pair<char, long long> >& editingWay
	){
	std::ofstream output(path);
	
	for (size_t i = 0; i < editingWay.size(); ++i){
		output << editingWay[i].first << keysReverse[editingWay[i].second] << endl;
	}
	output.close();
}
vector<pair<char,string> >  gettingChangesOfTwoFiles(
	const char* inputPath1 = "input1.txt",
	const char* inputPath2 = "input2.txt",
	const char* outputPath = "output.txt",
	int mode = 0){
	std::vector<std::string> listFromFirstInput = 
		getTextFromInput(inputPath1);
	std::vector<std::string> listFromSecondInput =
		getTextFromInput(inputPath2);

	std::map<std::string, long long> keys;
	std::vector<std::string> keysReverse;
	std::vector<long long> hashes1;
	std::vector<long long> hashes2;
	getHashesFromInput(listFromFirstInput, listFromSecondInput,
		keys, keysReverse, hashes1, hashes2);
	std::vector<std::pair<char, long long> > editingWay;
	int LCS_Difference = get_edit_distance(hashes1.begin(), hashes1.end(),
		hashes2.begin(), hashes2.end());
	
	Find_Editor_Path(hashes1.begin(), hashes1.end(), hashes2.begin(),
		hashes2.end(), LCS_Difference,editingWay);
	
	if (mode){
		outputEditorChanges(outputPath, keys, keysReverse, hashes1, hashes2, editingWay);
	}
	std::vector<std::pair<char, std::string> > stringResult;
	if (mode == 0){
		for (size_t i = 0; i < editingWay.size(); ++i){
			stringResult.push_back(make_pair(editingWay[i].first, keysReverse[editingWay[i].second]));
		}
	}
	return stringResult;
}
